#ifndef _KC_TOKEN_COLLECTION__H_KC_
#define _KC_TOKEN_COLLECTION__H_KC_

#include <iostream>
#include <list>
#include <boost/shared_ptr.hpp>
#include "Token.h"
 
namespace kc_sf
{

	class TokenCollection
	{
		public:

			// iteratory
			typedef std::list<Token >::iterator iterator;
			typedef std::list<Token >::const_iterator const_iterator;
			typedef std::list<Token >::reverse_iterator reverse_iterator;
			typedef std::list<Token >::const_reverse_iterator
					const_reverse_iterator;

			// konstruktory
			TokenCollection();
			explicit TokenCollection( const Token &token );
			TokenCollection( const_iterator begin, const_iterator end );
			TokenCollection( const TokenCollection &tokens );
			TokenCollection & operator=( const TokenCollection &tokens );

			// dodawanie elementów
			void push_front( const Token &token );
			void push_back( const Token &token );

			void add( iterator position, const Token &token );  // przed *position
			void concat( iterator position,
						 const TokenCollection &tokens );       // przed *position
			void concat( const TokenCollection &tokens );       // przed *position

			// usuwanie elementów
			void pop_front();
			void pop_back();

			iterator remove( iterator position );   // zwraca iterator na pierwszy element za usunietym
			void remove( iterator _start, iterator end );  // [_start, end)
			void removeAllAfter( iterator _after );        // bez _after
			void clear();

			void removeCfws();  // '\r', '\n', (comments), ' ', '\t'
			void removeFws();   // '\r', '\n', ' ', '\t'
			void removeType( int token_type );
			void removeTypes( std::list<int> token_types );

			// zmiana elementów
			void change( iterator _start,
						 iterator end,
						 const Token &to_what );                // [_start, end)

			void change( iterator _start,
						 iterator end,
						 const TokenCollection &to_what );      // [_start, end)

			// dostęp do elementów
			Token & head();                // throws Collection::PositionError
			const Token & head() const;    // throws Collection::PositionError

			Token & tail();                // throws Collection::PositionError
			const Token & tail() const;    // throws Collection::PositionError

			iterator begin();
			const_iterator begin() const;

			iterator end();
			const_iterator end() const;

			reverse_iterator rbegin();
			const_reverse_iterator rbegin() const;

			reverse_iterator rend();
			const_reverse_iterator rend() const;

			// inne
			bool empty() const;
			std::size_t size() const;

			// konwersja do napisu
			std::string
			toStr( std::list<int> ommitTokens = std::list<int>() ) const;    // [_start, end)

			std::string
			toStr( TokenCollection::const_iterator _start,
				   TokenCollection::const_iterator end,                     // [_start, end)
				   std::list<int> ommitTokens = std::list<int>() ) const;   // lista tokenow do ominiecia przy tworzeniu napisu


			// konwersja do strumienia znaków
			friend std::ostream &
			operator<<( std::ostream &out,
						const TokenCollection &tokens )
			{
				TokenCollection::const_iterator it = tokens.begin();
				for( ; it != tokens.end(); ++it )
					out << it->value();

				return out;
			}

		private:

			std::list<Token >   tc_tokens;
	};

	typedef TokenCollection::iterator       TokenPtr;
	typedef TokenCollection::const_iterator TokenConstPtr;

	typedef boost::shared_ptr<TokenCollection>       TokenCPtr;
	typedef boost::shared_ptr<const TokenCollection> TokenCConstPtr;

}

#endif // _KC_TOKEN_COLLECTION__H_KC_
